import type { GotoPageMethod, PageInfo } from '@/common/utils/type'
import { useUserStore } from '@/store'
import moment from 'moment'
import type { PaymentResult } from '@/service/api/type'

// 获取导航栏高度
export const getNavigationHeight = (): number => {
  const {windowWidth} = uni.getSystemInfoSync()
  const {height, top, right} = uni.getMenuButtonBoundingClientRect()
  return height + top + windowWidth - right
}

/**
 * 跳转指定页面
 * @param page 目标页面路径
 * @param method 跳转方式，默认为navigateTo
 */
export const gotoPage = (page: string, method: GotoPageMethod = 'navigateTo'): Promise<string | void> => {
  return new Promise<string | void>((resolve, reject) => {
    const handleError = async (error: any) => {
      if (error.innerError) {
        resolve()
      } else if (error.errMsg === 'navigateTo:fail webview count limit exceed') {
        // 页面栈到达上限
        await gotoPage('/pages/index/index', 'redirectTo')
      } else {
        reject(error)
      }
    }
    if (!!page || method === 'navigateBack') {
      if (method === 'navigateTo') {
        uni.navigateTo({
          url: page,
          success: () => resolve(),
          fail: err => handleError(err)
        })
      } else if (method === 'redirectTo') {
        uni.redirectTo({
          url: page,
          success: () => resolve(),
          fail: err => handleError(err)
        })
      } else if (method === 'switchTab') {
        uni.switchTab({
          url: page,
          success: () => resolve(),
          fail: err => handleError(err)
        })
      } else if (method === 'navigateBack') {
        uni.navigateBack({
          success: () => resolve(),
          fail: err => handleError(err)
        })
      }
    } else reject('Page cannot be empty.')
  })
}

// 计算两点距离
export const getDistance = (la1: number, lo1: number, newLocation: any, newLa: number, newLo: number): string => {
  let la2: number, lo2: number
  if (!!newLocation) {
    la2 = parseFloat(newLocation.substring(newLocation.indexOf(',') + 1))
    lo2 = parseFloat(newLocation.substring(0, newLocation.indexOf(',')))
  } else {
    la2 = newLa
    lo2 = newLo
  }
  const La1 = (la1 * Math.PI) / 180.0
  const La2 = (la2 * Math.PI) / 180.0
  const La3 = La1 - La2
  const Lb3 = (lo1 * Math.PI) / 180.0 - (lo2 * Math.PI) / 180.0
  let s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(La3 / 2), 2) + Math.cos(La1) * Math.cos(La2) * Math.pow(Math.sin(Lb3 / 2), 2)))
  s = s * 6378.137 //地球半径
  s = Math.round(s * 10000) / 10000
  if (Number((s * 1000).toFixed(0)) <= 100) {
    return '100m内'
  } else if (Number((s * 1000).toFixed(0)) > 100 && Number((s * 1000).toFixed(0)) < 1000) {
    return `${(s * 1000).toFixed(0)}m`
  } else if (Number((s * 1000).toFixed(0)) >= 1000 && Number((s * 1000).toFixed(0)) < 100000) {
    return `${s.toFixed(1)}km`
  } else if (Number((s * 1000).toFixed(0)) >= 100000) {
    return '大于100km'
  } else {
    return ''
  }
}

// 获取当前页面URL及参数
export const getCurrentPage = (): PageInfo => {
  const routes = getCurrentPages() //获取当前打开过的页面路由数组
  const curRoute = routes[routes.length - 1].route //获取当前页面路由
  //@ts-ignore
  const curParam = routes[routes.length - 1].options //获取路由参数
  //@ts-ignore
  const curFullUrl = routes[routes.length - 1].$page.fullPath
  // 拼接参数
  let param = ''
  for (let key in curParam) {
    param += '&' + key + '=' + curParam[key]
  }
  return {
    curFullUrl: curFullUrl,
    curUrl: curRoute,
    curParam: curParam
  }
}

// 申请获取订阅消息权限
export const requestSubscribeMessage = (): void => {
  const store = useUserStore()
  if (!store.$state.subscribeMessageStatus) {
    uni.getSetting({
      withSubscriptions: true,
      success: () => {
      }
    })
    uni.requestSubscribeMessage({
      tmplIds: ['CWgUABErs6MJkJRCuzxdob9tHJJMPJjc7W-XdtYMPzc'],
      success: res => {
        store.$state.subscribeMessageStatus = res.errMsg === 'requestSubscribeMessage:ok'
      },
      fail: error => {
        console.error(error)
        store.$state.subscribeMessageStatus = false
      }
    })
  }
}

// 获取无符号uuid
export const getNoSymbolUuid = (): string => {
  const S4 = (): string => (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1)
  return `${S4()}${S4()}${S4()}${S4()}${S4()}${S4()}${S4()}${S4()}`
}

// 今天所在周数（距离学期开始）
export const todayWeek = (firstDay: string, maxWeek: number): number => {
  if (moment().isBefore(moment(firstDay, 'yyyy-MM-DD'))) return 1
  const diff: number = moment().diff(moment(firstDay).startOf('day'), 'w')
  const offset: number = moment().day() >= moment(firstDay).day() ? 1 : 2
  const result = diff + offset <= 0 ? 1 : diff + offset > maxWeek ? maxWeek : diff + offset
  return result > maxWeek ? 0 : result
}

/**
 * 动态引入静态资源
 * @param url 资源路径，例如'/src/assets/images/...'
 * @returns {string} 返回资源路径
 */
export const getAssetsFile = (url: string) => {
  const modules = import.meta.globEager('/src/**/*.{png,svg,jpg,jpeg}')
  //@ts-ignore
  if (modules[url]) return modules[url].default
  return ''
}

// 调用支付接口
export const requestPayment = (paymentOptions: PaymentResult) => {
  const {nonceStr, paySign, packageValue, timeStamp, signType} = paymentOptions
  return new Promise((resolve, reject) => {
    // @ts-ignore
    uni.requestPayment({
      provider: 'wxpay',
      timeStamp,
      nonceStr,
      package: packageValue,
      signType,
      paySign,
      success: res => resolve(res),
      fail: err => reject(err)
    })
  })
}

/**
 * 数组根据key去重
 * @param listA 数组A
 * @param listB 数组B
 * @param key 用于去重的key属性
 */
export function arrayDedupe<T>(listA: T[], listB: T[], key: keyof T) {
  const set = new Set(listA.map(item => item[key]))
  return listB.filter(item => !set.has(item[key]))
}

/**
 * 数组合并去重
 * @param listA 数组A
 * @param listB 数组B
 * @param key 用于去重的key属性
 */
export function mergeAndDedupe<T>(listA: T[], listB: T[], key: keyof T) {
  return [...listA, ...arrayDedupe(listA, listB, key)]
}
